import dash
from dash import html, dcc
import plotly.express as px
from data_preprocessing import preprocess_airbnb_data
import os

# 初始化应用
app = dash.Dash(__name__)

# 加载和预处理数据
data_path = os.path.join('..', 'data', 'AB_NYC_2019.csv')
df = preprocess_airbnb_data(data_path)

# 创建应用布局
app.layout = html.Div([
    html.H1("纽约Airbnb三维分析仪表板", className='header'),

    dcc.Graph(id='3d-map', className='map-container'),

    html.Div([
        dcc.Dropdown(
            id='price-range',
            options=[
                {'label': '全部价格', 'value': 'all'},
                {'label': '低于$100', 'value': '<$100'},
                {'label': '$100-$200', 'value': '$100-200'},
                {'label': '$200-$300', 'value': '$200-300'},
                {'label': '高于$300', 'value': '$300+'}
            ],
            value='all',
            className='dropdown'
        ),

        dcc.Dropdown(
            id='room-type',
            options=[{'label': rt, 'value': rt} for rt in df['room_type'].unique()],
            value='Entire home/apt',
            className='dropdown'
        ),

        dcc.Slider(
            id='min-reviews',
            min=0,
            max=200,
            step=10,
            value=0,
            marks={i: str(i) for i in range(0, 201, 50)},
            className='slider'
        ),
    ], className='controls'),

    html.Div([
        html.P("纽约市Airbnb 2019数据集可视化分析", className='footer-note'),
        html.P(f"数据集包含: {len(df)} 个房源 | 平均价格: ${df['price'].mean():.2f}", className='stats')
    ], className='footer')
])


@app.callback(
    dash.dependencies.Output('3d-map', 'figure'),
    [dash.dependencies.Input('price-range', 'value'),
     dash.dependencies.Input('room-type', 'value'),
     dash.dependencies.Input('min-reviews', 'value')]
)
def update_map(price_range, room_type, min_reviews):
    # 应用过滤器
    filtered_df = df.copy()
    if price_range != 'all':
        filtered_df = filtered_df[filtered_df['price_category'] == price_range]
    if room_type:
        filtered_df = filtered_df[filtered_df['room_type'] == room_type]
    if min_reviews > 0:
        filtered_df = filtered_df[filtered_df['number_of_reviews'] >= min_reviews]

    # 创建可视化
    fig = px.scatter_3d(
        filtered_df,
        x='longitude', y='latitude', z='price',
        color='neighbourhood_group',
        hover_name='name',
        hover_data=['price', 'room_type'],
        size='number_of_reviews',
        size_max=15,
        title=f"过滤结果: {len(filtered_df)}个房源"
    )

    # 更新布局
    fig.update_layout(
        scene=dict(
            xaxis_title='经度',
            yaxis_title='纬度',
            zaxis_title='价格($)',
            camera=dict(eye=dict(x=1.5, y=1.5, z=0.8))
        ),
        margin=dict(l=0, r=0, b=30, t=40)
    )

    return fig


if __name__ == '__main__':
    app.run_server(debug=True, port=8050)